import Flutter
import ThingSmartDeviceKit
import ThingSmartHomeKit
import ThingSmartUtil
import ThingModuleServices
import ThingModuleManager
import ThingSmartActivatorDiscoveryManager
import ThingSmartBizCore
import ThingBluetoothInterface


import UIKit


@available(iOS 13.0, *)
@objc(TuyaHomeSdkFlutterPlugin)
 public class TuyaHomeSdkFlutterPlugin: NSObject, FlutterPlugin {
    /// MARK: private helper properties
    private let deviceSink = DeviceInfoStreamHandler()
    private weak var engine: FlutterEngine?
    private let deviceDiscoveryHandler = DeviceDiscoveryStreamHandler()
    private let batchConfigHandler = BleBatchConfigStreamHandler()
    var callback: FlutterResult?
    private var bleWifiConfigCallbacks: [String: FlutterResult] = [:]
     
    // 多设备同时配网
    private let maxConcurrentBleConfigs = 3
    private var bleWifiMultier: ThingSmartBLEWifiMultier?
    
    private var discoveredAdvModels: [String: ThingBLEAdvModel] = [:]
    
     private let homeInfoUpdateHandler = HomeInfoUpdateStreamHandler()
    var homeCallBack: FlutterResult?
     
     private var currentHome: ThingSmartHome?
     private var flutterVC: FlutterViewController?
     
    private var channel:FlutterMethodChannel?
     public static var instance: TuyaHomeSdkFlutterPlugin?
     
     
    
    private var devList =  [ThingSmartDevice]();
    
    func clearDeviceDelegates() {
        devList.forEach { $0.delegate = nil }
        devList.removeAll()
    }
     
    public static func setRoot(viewController: FlutterViewController) {
        instance?.flutterVC = viewController
    }
     
     
    public static func register(with registrar: FlutterPluginRegistrar) {
        let channel = FlutterMethodChannel(
            name: "tuya_home_sdk_flutter",
            binaryMessenger: registrar.messenger()
        )
        
        let deviceEvent = FlutterEventChannel(
            name: "tuya_home_sdk_flutter_device_dps_event",
            binaryMessenger: registrar.messenger()
        )
        let dscoveryEvent = FlutterEventChannel(
            name: "tuya_home_sdk_flutter_device_discovery_event",
            binaryMessenger: registrar.messenger()
        )
        
        let homeInfoEvent = FlutterEventChannel(
            name: "tuya_home_sdk_flutter_home_info_update_event",
            binaryMessenger: registrar.messenger()
        )
        
        let batchEvent = FlutterEventChannel(
            name: "tuya_home_sdk_flutter_ble_batch_event",
            binaryMessenger: registrar.messenger()
        )
        
        instance = TuyaHomeSdkFlutterPlugin()
  
        
        deviceEvent.setStreamHandler(instance?.deviceSink)
        dscoveryEvent.setStreamHandler(instance?.deviceDiscoveryHandler)
        homeInfoEvent.setStreamHandler(instance?.homeInfoUpdateHandler)
        batchEvent.setStreamHandler(instance?.batchConfigHandler)
        registrar.addMethodCallDelegate(instance!, channel: channel)
        
     
    }
     
   


    
     @objc(setEngine:)
     public static func set(engine: FlutterEngine)
     {
         guard let instance = instance else {
             return
         }
         instance.engine = engine
         instance.channel = FlutterMethodChannel(
            name: "native_to_flutter",
            binaryMessenger: engine.binaryMessenger)
        // 接收来自 Flutter 的原生指令（例如返回）
        instance.channel?.setMethodCallHandler({ [weak instance] call, result in
            guard let strongSelf = instance else { result(nil); return }
            switch call.method {
            case "nativePop":
                strongSelf.nativePop()
                result(nil)
         
            default:
                result(FlutterMethodNotImplemented)
            }
        })
     }
     
    public func handle(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        switch call.method {

        case "initSDK":
            initSdk(call, result: result)
        
        case "sendVerifyCodeWithUserName":
            sendVerifyCodeWithUserName(call, result: result)

        case "checkCodeWithUserName":
            checkCodeWithUserName(call, result: result)

        case "registerByUserName":
            registerByUserName(call, result: result)

        case "registerByPhone":
            registerByPhone(call, result: result)

        case "loginWithUserName":
            loginWithUserName(call, result: result)
        case "loginWithEmailPassword":
            loginWithEmailPassword(call, result: result)
        case "loginWithPhonePassword":
            loginWithPhonePassword(call, result: result)
        case "loginWithPhoneCode":
            loginWithPhoneCode(call, result: result)


       case "requestPrimaryCategory":
            requestPrimaryCategory(call, result: result)
            
        case "requestSecondaryCategory":
             requestSecondaryCategory(call, result: result)

        case "requestCategoryDetail":
             requestCategoryDetail(call, result: result)

        case "stopDiscoverDevices":
             stopDiscoverDevices(result: result)
            
        case "stopConfigWiFi":
            stopConfigWiFi(result: result)
        
         case "isLogin":
            isLogin(result: result)

        case "loginByAuth2":
            loginByAuth2(call, result: result)

        case "resetPasswordByEmail":
            resetPasswordByEmail(call, result: result)

        case "addHomeWithName":
            addHomeWithName(call, result: result)

        case "addShareMember":
            addShareMember(call, result: result)
            
        case "removeShareMember":
            removeShareMember(call, result: result)
            

        case "updateHome":
            updateHome(call, result: result)

        case "removeHome":
            removeHome(call, result: result)

        case "getHomeList":
            getHomeList(result: result)
            
        case "listenHomeInfo":
            listenHomeInfo(call, result: result)

        case "getHomeRooms":
            getHomeRooms(call, result: result)
        case "addRoom": addRoom(call, result: result)
        case "removeRoom": removeRoom(call, result: result)
        case "updateRoom": updateRoom(call, result: result)

        case "getHomeDevices":
            getHomeDevices(call, result: result)

        case "getDeviceById":
            getDeviceById(call, result: result)

        case "discoverDevices":
            discoverDevices(result: result)
            
        case "getWifiSsid": getWifiSsid(result: result)
        case "batchAppendBleDevice":
            appendBatchDevice(call, result: result)
        case "batchRemoveBleDevice":
            removeBatchDevice(call, result: result)
        case "startBatchConfigWifi":
            startBatchConfigWifi(call, result: result)
        case "stopBatchConfigWifi":
            stopBatchConfigWifi(result: result)

        case "startConfigBLEWifiDevice":
            startConfigBLEWifiDevice(call, result: result)

        case "getToken": requestHomeToken(call, result: result)
        case "requestHomeToken":
            requestHomeToken(call, result: result)

        case "startConfigWiFiDevice":
            startConfigWiFiDevice(call, result: result)

        case "startConfigQRCodeDevice":
            startConfigQRCodeDevice(call, result: result)

        case "startConfigWiredDevice":
            startConfigWiredDevice(call, result: result)

        case "startConfigSubDevice": startConfigSubDevice(call, result: result)

        case "publishDps": publishDps(call, result: result)

        case "removeDevice": removeDevice(call, result: result)
        case "renameDevice": updateDeviceName(call, result: result)
        case "getUserInfo": getUserInfo(result: result)

        case "assignDeviceToRoom": assignDeviceToRoom(call, result: result)

        case "listenForDevice": listenForDevice(call, result: result)

        case "updateUserNickName": updateUserNickName(call, result: result)

        case "updateUserIcon": updateUserIcon(call, result: result)

        case "logout": logout(result: result)
        case "getSceneList": getSceneList(call, result: result)

        case "fetchSceneDetail": fetchSceneDetail(call, result: result)
        case "addScene": addScene(call, result: result)
        case "removeScene": removeScene(call, result: result)
        case "runScene": runScene(call, result: result)
        case "changeAutomation": changeAutomation(call, result: result)
        case "editScene": editScene(call, result: result)
        case "addMember": addMember(call, result: result)
        case "queryMemberList": queryMemberList(call, result: result)
        case "getMemberShareList": getMemberShareList(call, result: result)
        case "removeMember": removeMember(call, result: result)
        case "modifyMember": modifyMember(call, result: result)
        case "joinHome": joinHome(call, result: result)
        case "cancelInvitation": cancelInvitation(call, result: result)
        case "acceptOrRejectInvitation":
            acceptOrRejectInvitation(call, result: result)
        case "queryInvitations": queryInvitation(call, result: result)
        case "modifyInvitation": modifyInvitation(call, result: result)
        case "getlatestMessage": getlatestMessage(call, result: result)
        case "gotoPanel": gotoPanel(call, result: result)
        case "gotoMessage": gotoMessage(call, result: result)
        case "openRNDebugConfig": openRNDebugConfig(call, result: result)
        default:
            result(FlutterMethodNotImplemented)
        }
    }

    private func initSdk(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let appKey = args["appKey"] as! String
        let secretKey = args["appSecret"] as! String
        let debug = args["isDebug"] as! Bool
       
 
        ThingSmartSDK.sharedInstance().start(withAppKey: appKey, secretKey: secretKey)
  
        ThingSmartSDK.sharedInstance().debugMode = debug
   
        result(true)

    }

    private func requestPrimaryCategory(
         _ call: FlutterMethodCall,
        result: @escaping FlutterResult)
    {
        let requestService = ThingSmartActivatorDiscoveryRequest()
        let requestData = ThingActivatorPrimaryCategoryRequestData()
        requestService.requestPrimaryCategory(withParam: requestData) { ret in
               let resultDic = ret.yy_modelToJSONObject()
            if let resultDic = resultDic{
                        result(resultDic)
                    } else {
                        print("nsData 为 nil 或转换失败")
                    }
            } failure: { error in
                if let error = error as? NSError {
                print("requestPrimaryCategory failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }
    }

    private func requestSecondaryCategory(
         _ call: FlutterMethodCall,
        result: @escaping FlutterResult)
    {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let levelOneCode = args["levelOneCode"] as! String
        let type = args["type"] as! String

       let requestService = ThingSmartActivatorDiscoveryRequest()
        let requestData =  ThingActivatorSecondaryCategoryRequestData()
        requestData.levelOneCode = levelOneCode
        requestData.type = type
        requestService.requestSecondaryCategory(withParam: requestData) { ret in
               let resultDic = ret.first!.yy_modelToJSONObject()
            if let resultDic = resultDic{
                        result(resultDic)
                    } else {
                        print("nsData 为 nil 或转换失败")
                    }
            } failure: { error in
                if let error = error as? NSError {
                print("requestSecondaryCategory failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }
    }

    private func requestCategoryDetail(
         _ call: FlutterMethodCall,
        result: @escaping FlutterResult)
    {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let bizType = args["bizType"] as! Int
        let bizValue = args["bizValue"] as! String

         let requestService = ThingSmartActivatorDiscoveryRequest()
        let requestData =  ThingActivatorCategoryDetailRequestData()
        requestData.bizType = NSNumber(value: bizType)
        requestData.bizValue = bizValue
        requestService.requestCategoryDetail(withParam: requestData) { ret in
               let resultDic = ret.yy_modelToJSONObject()
            if let resultDic = resultDic{
                        result(resultDic)
                    } else {
                        print("nsData 为 nil 或转换失败")
                    }
            } failure: { error in
                if let error = error as? NSError {
                print("requestCategoryDetail failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }
    }

    private func sendVerifyCodeWithUserName(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let username = args["username"] as! String
        let countryCode = args["country_code"] as! String
        let type = args["type"] as! Int
        let region = ThingSmartUser.sharedInstance().getDefaultRegion(
            withCountryCode: countryCode
        )
        
        ThingSmartUser.sharedInstance().sendVerifyCode(
            withUserName: username,
            region: region,
            countryCode: countryCode,
            type: type
        ) {
            print("sendVerifyCode success")
            result(true)
        } failure: { error in
            if let error = error as? NSError {
                print("sendVerifyCode failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }

    private func checkCodeWithUserName(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let username = args["username"] as! String
        let countryCode = args["country_code"] as! String
        let type = args["type"] as! Int
        let code = args["code"] as! String
        let region = ThingSmartUser.sharedInstance().getDefaultRegion(
            withCountryCode: countryCode
        )
        ThingSmartUser.sharedInstance().checkCode(
            withUserName: username,
            region: region,
            countryCode: countryCode,
            code: code,
            type: type,
            success: {
                isSuccess in
                if isSuccess {
                    result(true)
                } else {
                    result(false)
                }
            },
            failure: {
                error in
                if let error = error as? NSError {
                    print("sendVerifyCode failure: \(error)")
                    result(
                        FlutterError(
                            code: error.code.description,
                            message: error.description,
                            details: error.debugDescription
                        )
                    )
                }
            }
        )

    }

    private func registerByUserName(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let username = args["username"] as! String
        let countryCode = args["country_code"] as! String
        let password = args["password"] as! String
        let code = args["code"] as! String
        let region = ThingSmartUser.sharedInstance().getDefaultRegion(
            withCountryCode: countryCode
        )
        ThingSmartUser.sharedInstance().register(
            withUserName: username,
            region: region,
            countryCode: countryCode,
            code: code,
            password: password,
            success: {
                result(true)
            },
            failure: {
                error in
                if let error = error as? NSError {
                    print("sendVerifyCode failure: \(error)")
                    result(
                        FlutterError(
                            code: error.code.description,
                            message: error.description,
                            details: error.debugDescription
                        )
                    )
                }
            }
        )

    }

    private func registerByPhone(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let username = args["username"] as! String
        let countryCode = args["country_code"] as! String
        let password = args["password"] as! String
        let code = args["code"] as! String
        let region = ThingSmartUser.sharedInstance().getDefaultRegion(
            withCountryCode: countryCode
        )

        ThingSmartUser.sharedInstance().register(
            byPhone: countryCode,
            phoneNumber: username,
            password: password,
            code: code
        ) {
            result(true)
        } failure: {
            error in
            if let error = error as? NSError {
                print("sendVerifyCode failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }

    private func loginWithUserName(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let username = args["username"] as! String
        let countryCode = args["country_code"] as! String
        let password = args["password"] as! String

        ThingSmartUser.sharedInstance().login(
            byEmail: countryCode,
            email: username,
            password: password,
            success: {
                result(true)
            },
            failure: {
                error in
                if let error = error as? NSError {
                    print("sendVerifyCode failure: \(error)")
                    result(
                        FlutterError(
                            code: error.code.description,
                            message: error.description,
                            details: error.debugDescription
                        )
                    )
                }
            }
        )

    }

    private func loginWithPhonePassword(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let username = args["username"] as! String
        let countryCode = args["country_code"] as! String
        let password = args["password"] as! String

        ThingSmartUser.sharedInstance().login(
            byPhone: countryCode,
            phoneNumber: username,
            password: password,
            success: {
                result(true)
            },
            failure: {
                error in
                if let error = error as? NSError {
                    print("sendVerifyCode failure: \(error)")
                    result(
                        FlutterError(
                            code: error.code.description,
                            message: error.description,
                            details: error.debugDescription
                        )
                    )
                }
            }
        )

    }

     private func loginWithEmailPassword(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let username = args["username"] as! String
        let countryCode = args["country_code"] as! String
        let password = args["password"] as! String

        ThingSmartUser.sharedInstance().login(
            byEmail: countryCode,
            email: username,
            password: password,
            success: {
                result(true)
            },
            failure: {
                error in
                if let error = error as? NSError {
                    print("loginWithEmailPassword failure: \(error)")
                    result(
                        FlutterError(
                            code: error.code.description,
                            message: error.description,
                            details: error.debugDescription
                        )
                    )
                }
            }
        )
    }

    private func isLogin(result: @escaping FlutterResult) {
        let instance = ThingSmartUser.sharedInstance()
        result(instance.isLogin)
    }


   private func stopDiscoverDevices(result: @escaping FlutterResult) {
       print("119615stopDiscoverDevices")
        ThingSmartBLEManager.sharedInstance().delegate = nil
        ThingSmartBLEManager.sharedInstance().stopListening(false)
        result(nil)
    }
       
     private func stopConfigWiFi(result: @escaping FlutterResult) {
         _stopConfigWiFi()
        result(nil)
     }
     
     private func _stopConfigWiFi() {
        ThingSmartBLEWifiActivator.sharedInstance().bleWifiDelegate = nil
        ThingSmartBLEWifiActivator.sharedInstance().stopDiscover()
        ThingSmartActivator.sharedInstance()?.delegate = nil
        ThingSmartActivator.sharedInstance()?.stopConfigWiFi()
        cancelAllBleWifiConfigsIfNeeded(message: "配网已被终止")
     }

    private func loginWithPhoneCode(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let username = args["username"] as! String
        let countryCode = args["country_code"] as! String
        let code = args["code"] as! String
        ThingSmartUser.sharedInstance().login(
            withMobile: username,
            countryCode: countryCode,
            code: code
        ) {
            result(true)
        } failure: {
            error in
            if let error = error as? NSError {
                print("sendVerifyCode failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }
    }

    private func loginByAuth2(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let type = args["type"] as! String
        let countryCode = args["country_code"] as! String
        let accessToken = args["access_token"] as! String

        ThingSmartUser.sharedInstance().loginByAuth2(
            withType: type,
            countryCode: countryCode,
            accessToken: accessToken,
            extraInfo: [:]
        ) {
            result(true)
        } failure: { error in
            if let error = error as? NSError {
                print("loginByAuth2WithType failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }

    private func resetPasswordByEmail(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let username = args["username"] as! String
        let countryCode = args["country_code"] as! String
        let password = args["password"] as! String
        let code = args["code"] as! String

        ThingSmartUser.sharedInstance().resetPassword(
            byEmail: countryCode,
            email: username,
            newPassword: password,
            code: code
        ) {
            result(true)
        } failure: {
            error in
            if let error = error as? NSError {
                print("sendVerifyCode failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }

    private func getUserInfo(result: @escaping FlutterResult) {
        let instance = ThingSmartUser.sharedInstance()

        if instance.isLogin {
            var info = [String: Any]()
            info["username"] = instance.userName
            info["country_code"] = instance.countryCode
            info["email"] = instance.email
            info["ecode"] = instance.ecode
            info["phone_number"] = instance.phoneNumber
            info["partner_identity"] = instance.partnerIdentity
            info["nickname"] = instance.nickname
            info["head_icon_url"] = instance.headIconUrl

            info["sid"] = instance.sid
            info["is_login"] = instance.isLogin
            result(info)
        } else {
            result(nil)
        }

    }

    private func logout(result: @escaping FlutterResult) {
        ThingSmartUser.sharedInstance().loginOut {
            result(true)
        } failure: { err in
            result(false)
        }

    }

    private func updateUserNickName(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let nickname = args["nickname"] as! String
        ThingSmartUser.sharedInstance().updateNickname(
            nickname,
            success: {
                result(true)
            },
            failure: {
                error in
                result(false)
            }
        )
    }

    private func updateUserIcon(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let iconData = args["iconData"] as! String
        let dataDecoded: Data = Data(
            base64Encoded: iconData,
            options: .ignoreUnknownCharacters
        )!
        let image = UIImage(data: dataDecoded)

        ThingSmartUser.sharedInstance().updateHeadIcon(
            image!,
            success: {
                result(true)
            },
            failure: {
                error in
                result(false)
            }
        )
    }

    /// add home
    private func addHomeWithName(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let name = args["name"] as! String
        let latitude = args["latitude"] as! Double
        let longitude = args["longitude"] as! Double
        let geoName = args["geoName"] as! String
        let rooms = args["rooms"] as! [String]
        let homeManager = ThingSmartHomeManager()

        homeManager.addHome(
            withName: name,
            geoName: geoName,
            rooms: rooms,
            latitude: latitude,
            longitude: longitude,
            success: {
                (homeId) in
              
                let home = ThingSmartHome(homeId: homeId)
                guard let familyProtocol = ThingSmartBizCore.sharedInstance().service(of: ThingFamilyProtocol.self) as? ThingFamilyProtocol else {
                    return
                }
                familyProtocol.updateCurrentFamilyId?(homeId)
                
                result(homeId)
            },
            failure: {
                (error) in
                if let error = error as? NSError {
                    print("addHomeWithName failure: \(error)")
                    result(
                        FlutterError(
                            code: error.code.description,
                            message: error.description,
                            details: error.debugDescription
                        )
                    )
                }

            }
        )

    }

    private func updateHome(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let homeId = args["homeId"] as! Int64
        let name = args["name"] as! String
        let latitude = args["latitude"] as! Double
        let longitude = args["longitude"] as! Double

        let rooms = args["rooms"] as! [String]

        let home = ThingSmartHome(homeId: homeId)
        guard let familyProtocol = ThingSmartBizCore.sharedInstance().service(of: ThingFamilyProtocol.self) as? ThingFamilyProtocol else {
            return
        }
        familyProtocol.updateCurrentFamilyId?(homeId)
        home?.updateInfo(
            withName: name,
            geoName: name,
            latitude: latitude,
            longitude: longitude,
            rooms: rooms,
            overWriteRoom: true,
            success: {
                result(true)
            },
            failure: { error in

                if let error = error as? NSError {
                    print("addHomeWithName failure: \(error)")
                    result(
                        FlutterError(
                            code: error.code.description,
                            message: error.description,
                            details: error.debugDescription
                        )
                    )
                }
            }
        )
    }

    
 private func addShareMember(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {

       let args = call.arguments as? [String: Any] ?? [:]

     let userAccount = args["userAccount"] as? String ?? ""
     let devIds = args["devIdList"] as? [String] ?? []
     let homeId = args["homeId"] as? Int64 ?? 0

     if userAccount.isEmpty || devIds.isEmpty || homeId == 0 {
    // error
        result(FlutterError(code: "InvalidArgs", message: "userAccount or devIdList or homeId is empty", details: nil))
            return
        }

        let deviceShare = ThingSmartHomeDeviceShare()
        let model = ThingSmartDeviceShareRequestModel()
        
        currentHome = ThingSmartHome(homeId: homeId)
        currentHome?.delegate = self;
        model.homeID = currentHome!.homeId
        model.countryCode = "86"
        model.userAccount = userAccount
        model.devIds = devIds

        deviceShare.add(with: model) {  _ in
            print("addShareMember success")
            result(true)
        }  failure: { (error) in
            if let error = error as? NSError {
                print("addShareMember failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }

        }
    }
     
     private func removeShareMember(
         _ call: FlutterMethodCall,
         result: @escaping FlutterResult
     ) {
         let args = call.arguments as? [String: Any] ?? [:]
         let memberId = args["memberId"] as? Int ?? 0
         if memberId == 0 {
             result(FlutterError(code: "InvalidArgs", message: "memberId is empty", details: nil))
              return
         }
         
         let deviceShare = ThingSmartHomeDeviceShare()
         deviceShare.removeMember(withMemberId: memberId){
             print("removeShareMember success")
             result(true)
         } failure: { _ in
             print("removeShareMember failed")
             result(false)
         }
     }

    private func removeHome(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let homeId = args["homeId"] as! Int64
        let home = ThingSmartHome(homeId: homeId)
        home?.dismiss(
            success: {
                result(true)
            },
            failure: { error in
                result(false)
            }

        )
    }
     
     

     

    /// Get Home List

    private func getHomeList(result: @escaping FlutterResult) {
        let homeManager = ThingSmartHomeManager()
        homeManager.getHomeList(
            success: { (list) in
                var homes = [[String: Any]]()

                guard let list else {
                    return
                }
          
                list.forEach { (model) in

                    var home = [String: Any]()
                    home["homeId"] = model.homeId
                    home["name"] = model.name
                    home["geoName"] = model.geoName
                    home["latitude"] = model.latitude
                    home["longitude"] = model.longitude
                    home["backgroundUrl"] = model.backgroundUrl
                    home["role"] = model.role.rawValue
                    home["dealStatus"] = model.dealStatus.rawValue
                    home["managementStatus"] = model.managementStatus
                    home["nickName"] = model.nickName

                    homes.append(home)
                }
                
                guard let familyProtocol = ThingSmartBizCore.sharedInstance().service(of: ThingFamilyProtocol.self) as? ThingFamilyProtocol else {
                    return
                }
                familyProtocol.updateCurrentFamilyId?(homes.first?["homeId"] as! Int64)
                result(homes)
            },
            failure: { (error) in
                if let error = error as? NSError {
                    print("getHomeList failure: \(error)")
                    result(
                        FlutterError(
                            code: error.code.description,
                            message: error.description,
                            details: error.debugDescription
                        )
                    )
                }

            }
        )
    }
     
     
     private func listenHomeInfo( _ call: FlutterMethodCall, result: @escaping FlutterResult) {
         let args = call.arguments as? [String: Any] ?? [String: Any]()
         let homeId = args["homeId"] as! Int64
         currentHome = ThingSmartHome(homeId: homeId)
         currentHome?.delegate = self;

         result(true)
     }

    private func startConfigBLEWifiDevice(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let ssid = args["ssid"] as! String
        let password = args["password"] as! String
        let timeout = args["timeout"] as! Int
        let homeId = args["homeId"] as! Int64
        let uuid = (args["uuid"] as! String).lowercased()
        let productId = args["productId"] as! String
        
        guard bleWifiConfigCallbacks.count < maxConcurrentBleConfigs else {
            result(
                FlutterError(
                    code: "MAX_CONFIG_IN_PROGRESS",
                    message: "最多支持三台设备同时配网",
                    details: nil
                )
            )
            return
        }
        
        guard bleWifiConfigCallbacks[uuid] == nil else {
            result(
                FlutterError(
                    code: "CONFIG_IN_PROGRESS",
                    message: "该设备正在配网",
                    details: nil
                )
            )
            return
        }
        
        DispatchQueue.main.async { [weak self] in
            guard let self = self else { return }
            NSLog("delegate before start: \(String(describing: ThingSmartBLEWifiActivator.sharedInstance().bleWifiDelegate))")
            bleWifiConfigCallbacks[uuid] = result
            NSLog("TuyaHomeSdkFlutterPlugin startConfigBLEWifiDevice on thread: \(Thread.current)")
            ThingSmartBLEWifiActivator.sharedInstance().bleWifiDelegate = nil
            ThingSmartBLEWifiActivator.sharedInstance().bleWifiDelegate = self
            ThingSmartBLEWifiActivator.sharedInstance()
                .startConfigBLEWifiDevice(
                    withUUID: uuid,
                    homeId: homeId,
                    productId: productId,
                    ssid: ssid,
                    password: password,
                    timeout: TimeInterval(timeout)
                ) { } failure: { [weak self] in
                    guard let self = self else { return }
                    self.finishBleWifiConfig(
                        for: uuid,
                        withError: FlutterError(
                            code: "-1",
                            message: "配网失败",
                            details: nil
                        )
                    )
                }
        }
       
       

    }

    private func startConfigWiFiDevice(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let ssid = args["ssid"] as! String
        let password = args["password"] as! String

        let timeout = args["timeout"] as! Int
        let token = args["token"] as! String
        self.callback = result

        ThingSmartActivator.sharedInstance()?.delegate = self
        ThingSmartActivator.sharedInstance()?.startConfigWiFi(
            .AP,
            ssid: ssid,
            password: password,
            token: token,
            timeout: TimeInterval(timeout)
        )

    }

    private func startConfigQRCodeDevice(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let qrCode = args["qrCode"] as! String
        let ssid = args["ssid"] as! String
        let password = args["password"] as! String
        let timeout = args["timeout"] as! Int
        let homeId = args["homeId"] as! Int64

        self.callback = result
        ThingSmartActivator.sharedInstance()?.delegate = self

        ThingSmartActivator.parseQRCode(
            qrCode,
            success: { [weak self] parsed in
                guard let self = self else { return }
                guard let dict = parsed as? [String: Any],
                      let actionData = dict["actionData"] as? [String: Any],
                      let uuid = actionData["uuid"] as? String,
                      uuid.isEmpty == false else {
                    self.callback?(FlutterError(
                        code: "QR_PARSE_ERROR",
                        message: "Invalid QR code payload",
                        details: nil
                    ))
                    return
                }

                ThingSmartActivator.sharedInstance()?.getTokenWithUUID(
                    uuid,
                    homeId: homeId,
                    success: { token in
                        guard let token = token, token.isEmpty == false else {
                            self.callback?(FlutterError(
                                code: "TOKEN_EMPTY",
                                message: "Token is empty",
                                details: nil
                            ))
                            return
                        }
                        ThingSmartActivator.sharedInstance()?.startConfigWiFi(
                            .EZ,
                            ssid: ssid,
                            password: password,
                            token: token,
                            timeout: TimeInterval(timeout)
                        )
                    },
                    failure: { error in
                        if let error = error as NSError? {
                            self.callback?(FlutterError(
                                code: error.code.description,
                                message: error.description,
                                details: error.debugDescription
                            ))
                        } else {
                            self.callback?(FlutterError(
                                code: "TOKEN_ERROR",
                                message: "Failed to get token by UUID",
                                details: nil
                            ))
                        }
                    }
                )
            },
            failure: { [weak self] error in
                guard let self = self else { return }
                if let error = error as NSError? {
                    self.callback?(FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    ))
                } else {
                    self.callback?(FlutterError(
                        code: "QR_ERROR",
                        message: "Failed to parse QR code",
                        details: nil
                    ))
                }
            }
        )
    }

    private func startConfigWiredDevice(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()

        let timeout = args["timeout"] as! Int
        let token = args["token"] as! String
        self.callback = result

        ThingSmartActivator.sharedInstance()?.delegate = self

        ThingSmartActivator.sharedInstance()?.startConfigWiFi(
            withToken: token,
            timeout: TimeInterval(timeout)
        )

    }

    private func startConfigSubDevice(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()

        let timeout = args["timeout"] as! Int
        let devId = args["devId"] as! String
        self.callback = result

        ThingSmartActivator.sharedInstance()?.delegate = self
        ThingSmartActivator.sharedInstance()?.activeSubDevice(
            withGwId: devId,
            timeout: TimeInterval(timeout)
        )

    }

    private func appendBatchDevice(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [:]
        guard let uuid = args["uuid"] as? String, uuid.isEmpty == false else {
            result(FlutterError(
                code: "BATCH_PARAM",
                message: "uuid 参数无效",
                details: nil
            ))
            return
        }
        guard let adv = discoveredAdvModels[uuid.lowercased()] else {
            result(FlutterError(
                code: "BATCH_NOT_FOUND",
                message: "未找到对应的蓝牙广播信息，无法加入批量队列",
                details: nil
            ))
            return
        }
        let multier = ensureBleWifiMultier()
        multier.appendDevice(adv)
        result(true)
    }

    private func removeBatchDevice(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [:]
        guard let uuid = args["uuid"] as? String, uuid.isEmpty == false else {
            result(FlutterError(
                code: "BATCH_PARAM",
                message: "uuid 参数无效",
                details: nil
            ))
            return
        }
        guard let adv = discoveredAdvModels[uuid.lowercased()],
              let multier = bleWifiMultier else {
            result(true)
            return
        }
        multier.removeDevice(adv)
        result(true)
    }

    private func startBatchConfigWifi(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [:]
        guard
            let ssid = args["ssid"] as? String,
            let password = args["password"] as? String,
            let token = args["token"] as? String
        else {
            result(FlutterError(
                code: "BATCH_PARAM",
                message: "ssid/password/token 参数缺失",
                details: nil
            ))
            return
        }
        let config = ThingSmartBLEWifiConfiguration()
        config.ssid = ssid
        config.pwd = password
        config.token = token

        let multier = ensureBleWifiMultier()
        multier.config = config
        multier.delegate = self
        multier.startConfigWifi()
        result(true)
    }

    private func stopBatchConfigWifi(result: @escaping FlutterResult) {
        bleWifiMultier?.stopConfigWifi()
        bleWifiMultier?.delegate = nil
        bleWifiMultier = nil
        result(true)
    }

    private func ensureBleWifiMultier() -> ThingSmartBLEWifiMultier {
        if bleWifiMultier == nil {
            bleWifiMultier = ThingSmartBLEWifiMultier()
            bleWifiMultier?.delegate = self
        }
        return bleWifiMultier!
    }

    private func requestHomeToken(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let homeId = args["homeId"] as! Int64

        ThingSmartActivator.sharedInstance()?.getTokenWithHomeId(
            homeId,
            success: { [weak self] (token) in
                guard self != nil else { return }

                result(token)

            },
            failure: { (error) in
                let nsError = error as NSError?
                let code = "\(nsError?.code ?? -1)"
                let message = nsError?.localizedDescription ?? "Cannot Get token"
                result(
                    FlutterError(
                        code: code,
                        message: message,
                        details: nil
                    )
                )

            }
        )
    }

    private func discoverDevices(result: @escaping FlutterResult) {
        _stopConfigWiFi()
        self.callback = result
        ThingSmartBLEManager.sharedInstance().delegate = self
        ThingSmartBLEManager.sharedInstance().startListening(true)
    }

    private func getWifiSsid(result: @escaping FlutterResult) {
        let locationManager = CLLocationManager()
        locationManager.requestWhenInUseAuthorization()
        ThingSmartActivator.getSSID(
            {
                wifiSsid in
                result(wifiSsid)
            },
            failure: {
                (error) in
                if let error = error as? NSError {
                    print("getWifiSsid failure: \(error)")
                    result(
                        FlutterError(
                            code: error.code.description,
                            message: error.description,
                            details: error.debugDescription
                        )
                    )
                }
            }
        )

    }

    private func getHomeRooms(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let homeId = args["homeId"] as! Int64
        let home = ThingSmartHome(homeId: homeId)
        home?.getDataWithSuccess(
            {
                local in
                var rooms = [[String: Any]]()
                home?.roomList.forEach({
                    roomModel in
                    var room = [String: Any]()
                    room["id"] = roomModel.roomId
                    room["name"] = roomModel.name
                    rooms.append(room)
                })
                result(rooms)
            },
            failure: {
                error in

                if let error = error as? NSError {
                    print("getHomeRooms failure: \(error)")
                    result(
                        FlutterError(
                            code: error.code.description,
                            message: error.description,
                            details: error.debugDescription
                        )
                    )
                }
            }
        )
    }

    private func addRoom(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let homeId = args["homeId"] as! Int64
        let roomName = args["roomName"] as! String

        ThingSmartHome(homeId: homeId).addRoom(withName: roomName) {
            roomModel in
            var room = [String: Any]()
            room["id"] = roomModel.roomId
            room["name"] = roomModel.name

            result(room)
        } failure: { error in
            if let error = error as? NSError {
                print("getHomeList failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }

    private func removeRoom(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let homeId = args["homeId"] as! Int64
        let roomId = args["roomId"] as! Int64

        ThingSmartHome(homeId: homeId).removeRoom(withRoomId: roomId) {
            result(true)
        } failure: { error in
            if let error = error as? NSError {
                print("getHomeList failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }

    private func updateRoom(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let homeId = args["homeId"] as! Int64
        let roomName = args["roomName"] as! String
        let roomId = args["roomId"] as! Int64
        ThingSmartRoom(roomId: roomId, homeId: homeId).updateName(roomName) {
            result(true)
        } failure: { error in
            if let error = error as? NSError {
                print("getHomeList failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }

    private func getHomeDevices(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let homeId = args["homeId"] as! Int64
        let home = ThingSmartHome(homeId: homeId)
        currentHome = ThingSmartHome(homeId: homeId)
        home?.getDataWithSuccess(
            {
                local in
                var devices = [[String: Any]]()
                
                home?.deviceList.forEach({
                    deviceModel in
                    let dict = self._modelToDict(deviceModel: deviceModel)
                    devices.append(dict)
                    
                })
                home?.sharedDeviceList.forEach({
                deviceModel in
                let dict = self._modelToDict(deviceModel: deviceModel)
                devices.append(dict)
                })
                result(devices)
            },
            failure: {
                error in

                if let error = error as? NSError {
                    print("getWifiSsid failure: \(error)")
                    result(
                        FlutterError(
                            code: error.code.description,
                            message: error.description,
                            details: error.debugDescription
                        )
                    )
                }

            }
        )
    }

    private func getDeviceById(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let deviceId = args["deviceId"] as! String

        let device = ThingSmartDevice(deviceId: deviceId)
        guard let model = device?.deviceModel else {
            result(
                FlutterError(
                    code: "DeviceNotFound",
                    message: "ThingSmartDevice not found for given deviceId",
                    details: nil
                )
            )
            return
        }

        let dict = self._modelToDict(deviceModel: model)
        result(dict)
    }

     
     
    private func listenForDevice(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let deviceId = args["deviceId"] as! String
        guard let device = ThingSmartDevice(deviceId: deviceId) else {
            print("device is nil")
            result(
                FlutterError(
                    code: "Thing Smart device ",
                    message: "device is nil",
                    details: nil
                )
            )
            return
        }

        device.delegate = self
        if devList.contains(where: { $0.deviceModel.devId == deviceId }) == false {
            devList.append(device)
        }
        result(true)
    }

    private func publishDps(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let deviceId = args["deviceId"] as! String
        let dps = args["dps"] as! [String: Any]

        //        let home = ThingSmartHome(homeId: 98744020)
        //        home?.getDetailWithSuccess({
        //            local in
        //
        //        }, failure: {
        //            error in
        //        })

        guard let device = ThingSmartDevice(deviceId: deviceId) else {
            print("device is nil")
            result(
                FlutterError(
                    code: "Thing Smart device ",
                    message: "device is nil",
                    details: nil
                )
            )
            return
        }

        device.delegate = self
        device.publishDps(
            dps,
            success: {
                result(true)
            },
            failure: {
                (error) in
                if let error = error as? NSError {
                    print("publishDps failure: \(error)")
                    result(
                        FlutterError(
                            code: error.code.description,
                            message: error.description,
                            details: error.debugDescription
                        )
                    )
                }
            }
        )
    }

    private func removeDevice(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let deviceId = args["deviceId"] as! String
        let device = ThingSmartDevice(deviceId: deviceId)
        device?.remove(
            {
                result(true)
            },
            failure: {
                (error) in
                if let error = error as? NSError {
                    print("removeDevice failure: \(error)")
                    result(
                        FlutterError(
                            code: error.code.description,
                            message: error.description,
                            details: error.debugDescription
                        )
                    )
                }
            }
        )
    }

    private func updateDeviceName(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let deviceId = args["deviceId"] as! String
        let name = args["name"] as! String

        let device = ThingSmartDevice(deviceId: deviceId)
        device?.updateName(name) {
            result(true)
        } failure: { error in
            if let error = error as? NSError {
                print("updateDeviceName failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }

    /// assign device to room
    private func assignDeviceToRoom(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let roomId = args["roomId"] as! Int64
        let deviceId = args["deviceId"] as! String
        let homeId = args["homeId"] as! Int64

        let room = ThingSmartRoom(roomId: roomId, homeId: homeId)

        room!.addDevice(
            withDeviceId: deviceId,
            success: {
                result(true)
                print("  assignDeviceToRoom success")
            },
            failure: {
                (error) in
                if let error = error as? NSError {
                    print("assignDeviceToRoom failure: \(error)")
                    result(
                        FlutterError(
                            code: error.code.description,
                            message: error.description,
                            details: error.debugDescription
                        )
                    )
                }
            }
        )

    }

    // MARK: private helper methods
    private func finishBleWifiConfig(
        for uuid: String,
        withSuccess data: [String: Any]? = nil,
        withError error: FlutterError? = nil
    ) {
        let key = uuid.lowercased()
        guard let callback = bleWifiConfigCallbacks.removeValue(forKey: key)
        else { return }
        discoveredAdvModels.removeValue(forKey: uuid.lowercased())
        if let data = data {
            callback(data)
        } else if let error = error {
            callback(error)
        } else {
            callback(
                FlutterError(
                    code: "Config",
                    message: "配网结果未知",
                    details: nil
                )
            )
        }
        if bleWifiConfigCallbacks.isEmpty {
            ThingSmartBLEWifiActivator.sharedInstance().bleWifiDelegate = nil
            ThingSmartBLEWifiActivator.sharedInstance().stopDiscover()
        }
    }

    private func cancelAllBleWifiConfigsIfNeeded(message: String) {
        guard !bleWifiConfigCallbacks.isEmpty else { return }
        let callbacks = bleWifiConfigCallbacks
        bleWifiConfigCallbacks.removeAll()
        for (_, callback) in callbacks {
            callback(
                FlutterError(
                    code: "Config",
                    message: message,
                    details: nil
                )
            )
        }
        ThingSmartBLEWifiActivator.sharedInstance().bleWifiDelegate = nil
        ThingSmartBLEWifiActivator.sharedInstance().stopDiscover()
    }

    private func extractUUID(from activator: ThingSmartBLEWifiActivator) -> String? {
        return activator.value(forKey: "_uuid") as? String
    }

    private func _modelToDict(deviceModel: ThingSmartDeviceModel) -> [String:
        Any]
    {
        var dict = [String: Any]()
        dict["uiName"] = deviceModel.uiName
        dict["devId"] = deviceModel.devId
        dict["name"] = deviceModel.name
        dict["iconUrl"] = deviceModel.iconUrl
        dict["isOnline"] = deviceModel.isOnline
        dict["isCloudOnline"] = deviceModel.isCloudOnline
        dict["isLocalOnline"] = deviceModel.isLocalOnline
        dict["isShare"] = deviceModel.isShare
        dict["dps"] = deviceModel.dps
        dict["dpCodes"] = deviceModel.dpCodes
        dict["productId"] = deviceModel.productId
        dict["capability"] = deviceModel.capability
        dict["supportGroup"] = deviceModel.supportGroup
        dict["gwType"] = deviceModel.gwType
        dict["pv"] = deviceModel.pv
        dict["lpv"] = deviceModel.lpv
        dict["latitude"] = deviceModel.latitude
        dict["longitude"] = deviceModel.longitude
        dict["localKey"] = deviceModel.localKey
        dict["uuid"] = deviceModel.uuid
        dict["homeId"] = deviceModel.homeId
        dict["roomId"] = deviceModel.roomId
        dict["timezoneId"] = deviceModel.timezoneId
        dict["nodeId"] = deviceModel.nodeId
        dict["parentId"] = deviceModel.parentId
        dict["isMeshBleOnline"] = deviceModel.isMeshBleOnline
        dict["devKey"] = deviceModel.devKey
        dict["standard"] = deviceModel.standard
        dict["activeTime"] = deviceModel.activeTime
        dict["homeDisplayOrder"] = deviceModel.homeDisplayOrder
        dict["sharedTime"] = deviceModel.sharedTime
        dict["accessType"] = deviceModel.accessType
        dict["schema"] = deviceModel.schema
        dict["category"] = deviceModel.category
        dict["categoryCode"] = deviceModel.categoryCode
        dict["cadv"] = deviceModel.cadv
        dict["dpName"] = deviceModel.dpName
        dict["productVer"] = deviceModel.productVer
        dict["uiId"] = deviceModel.uiId
        dict["vendorInfo"] = deviceModel.vendorInfo

        return dict
    }

    // MARK: Scene managment

    public func getSceneList(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()

        let homeId = args["homeId"] as! Int64
        ThingSmartSceneManager.sharedInstance()?.getSimpleSceneList(
            withHomeId: homeId
        ) { list in

            var scenes = [[String: Any?]]()

            list.forEach({
                item in

                scenes.append(item.toDictionary())
            })
            result(scenes)

        } failure: { error in
            if let error = error as? NSError {
                print("getSceneList failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }

    public func fetchSceneDetail(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args: [String: Any] = call.arguments as! [String: Any]
        let sceneId = args["sceneId"] as! String
        let homeId = args["homeId"] as! Int64
        let ruleGenre = args["ruleGenre"] as! Int
        let supportHome = args["supportHome"] as! Bool
        let details = TSceneDetailParams()
        details.sceneId = sceneId
        details.gid = homeId
        details.ruleGenre = ThingSmartSceneRuleGenre.init(
            rawValue: UInt(ruleGenre)
        )!
        details.supportHome = supportHome

        ThingSmartSceneManager.sharedInstance().fetchSceneDetail(with: details)
        { model in

            result(model.toDictionary())
        } failure: { error in
            if let error = error as? NSError {
                print("fetchSceneDetail failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }

    @available(iOS 13.0, *)
    func getThingSmartSceneDPModel(_ devId: String) async
        -> [ThingSmartSceneDPModel]?
    {
        await withCheckedContinuation { cont in
            ThingSmartSceneManager.sharedInstance()?.getCondicationDeviceDPList(
                withDevId: devId
            ) { list in
                cont.resume(returning: list)
            } failure: { _ in
                cont.resume(returning: nil)
            }
        }
    }

    private func addScene(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args: [String: Any] = call.arguments as! [String: Any]
        let jsonData = try! JSONSerialization.data(
            withJSONObject: args

        )

        do {
            let factory = try JSONDecoder().decode(
                ThingSmartSceneFactory.self,
                from: jsonData
            )

            Task {
                // ❷ collect needed DP models first
                var dpCache: [String: [ThingSmartSceneDPModel]?] = [:]  // key = devId
                for cond in factory.conditions! {
                    if dpCache[cond.deviceId!] == nil {  // fetch once per device
                        dpCache[cond.deviceId!] =
                            await getThingSmartSceneDPModel(cond.deviceId!)
                    }
                }

                // ❸ build lists now that the data is ready
                let preConditions = factory.preConditions!.map {
                    $0.toThingModel()!
                }
                let conditions = factory.conditions!.map { sceneCondition in
                    sceneCondition.toThingModel { devId, dpId in
                        (dpCache[devId]!!).first { $0.dpId == dpId }
                    }!
                }

                let actions = factory.actions!.map { $0.toTuyaModel() }

                ThingSmartScene.addNewScene(
                    withName: factory.name,
                    homeId: Int64(factory.homeId!),
                    background: "",
                    showFirstPage: factory.showFirstPage!,
                    preConditionList: preConditions,
                    conditionList: conditions,
                    actionList: actions,
                    matchType: ThingSmartConditionMatchType(
                        rawValue: UInt(factory.matchType!)
                    )!
                ) { model in
                    result(model?.toDictionary())
                } failure: { error in
                    if let error = error as? NSError {
                        print("addScene failure: \(error)")
                        result(
                            FlutterError(
                                code: error.code.description,
                                message: error.description,
                                details: error.debugDescription
                            )
                        )
                    }
                }

            }

        } catch {
            result(
                FlutterError(
                    code: "DECODE_ERROR",
                    message: error.localizedDescription,
                    details: nil
                )
            )
        }

    }

    private func editScene(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args: [String: Any] = call.arguments as! [String: Any]
        let jsonData = try! JSONSerialization.data(
            withJSONObject: args

        )

        do {
            let factory = try JSONDecoder().decode(
                ThingSmartSceneFactory.self,
                from: jsonData
            )

            Task {
                // ❷ collect needed DP models first
                var dpCache: [String: [ThingSmartSceneDPModel]?] = [:]  // key = devId
                let sceneModel = ThingSmartSceneModel()
                sceneModel.sceneId = factory.id!
                if factory.name != nil {
                    sceneModel.name = factory.name!
                }

                if factory.conditions != nil {
                    for cond in factory.conditions! {
                        if dpCache[cond.deviceId!] == nil {  // fetch once per device
                            dpCache[cond.deviceId!] =
                                await getThingSmartSceneDPModel(cond.deviceId!)
                        }
                    }
                    let conditions = factory.conditions!.map { sceneCondition in
                        sceneCondition.toThingModel { devId, dpId in
                            (dpCache[devId]!!).first { $0.dpId == dpId }
                        }!
                    }
                    sceneModel.conditions = conditions
                }

                if factory.preConditions != nil {
                    // ❸ build lists now that the data is ready
                    let preConditions = factory.preConditions!.map {
                        $0.toThingModel()!
                    }
                    sceneModel.preConditions = preConditions
                }

                if factory.actions != nil {
                    let actions = factory.actions!.map { $0.toTuyaModel() }
                    sceneModel.actions = actions
                }

                if factory.showFirstPage != nil {
                    sceneModel.stickyOnTop = factory.showFirstPage!
                }

                if factory.matchType != nil {
                    sceneModel.matchType = ThingSmartConditionMatchType(
                        rawValue: UInt(factory.matchType!)
                    )!
                }

                let scene = ThingSmartScene(sceneModel: sceneModel)

                scene?.modifyScene(with: sceneModel) {
                    result(true)
                } failure: { error in
                    if let error = error as? NSError {
                        print("editScene failure: \(error)")
                        result(
                            FlutterError(
                                code: error.code.description,
                                message: error.description,
                                details: error.debugDescription
                            )
                        )
                    }
                }

            }

        } catch {
            result(
                FlutterError(
                    code: "DECODE_ERROR",
                    message: error.localizedDescription,
                    details: nil
                )
            )
        }
    }

    private func removeScene(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()

        let sceneId = args["sceneId"] as! String
        let homeId = args["homeId"] as! Int64

        let sceneModel = ThingSmartSceneModel()
        sceneModel.sceneId = sceneId
        let scene = ThingSmartScene(sceneModel: sceneModel)
        scene?.delete(withHomeId: homeId) { value in
            result(value)
        } failure: { error in
            if let error = error as? NSError {
                print("addScene failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }

    private func runScene(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let sceneId = args["sceneId"] as! String
        let sceneModel = ThingSmartSceneModel()
        sceneModel.sceneId = sceneId
        let scene = ThingSmartScene(sceneModel: sceneModel)
        scene?.execute {
            result(true)
        } failure: { error in
            if let error = error as? NSError {
                print("addScene failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }

    private func changeAutomation(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let sceneId = args["sceneId"] as! String
        let status = args["status"] as! Bool
        let sceneModel = ThingSmartSceneModel()
        sceneModel.sceneId = sceneId
        let scene = ThingSmartScene(sceneModel: sceneModel)

        if status {
            scene?.enable {
                result(true)
            } failure: { error in
                if let error = error as? NSError {
                    print("addScene failure: \(error)")
                    result(
                        FlutterError(
                            code: error.code.description,
                            message: error.description,
                            details: error.debugDescription
                        )
                    )
                }
            }

        } else {
            scene?.disableScene {
                result(true)
            } failure: { error in
                if let error = error as? NSError {
                    print("addScene failure: \(error)")
                    result(
                        FlutterError(
                            code: error.code.description,
                            message: error.description,
                            details: error.debugDescription
                        )
                    )
                }
            }

        }

    }

    // Member Management

    private func addMember(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let homeId = args["homeId"] as! Int64
        let name = args["name"] as! String
        let autoAccept = args["autoAccept"] as! Bool
        let countryCode = args["countryCode"] as? String
        let account = args["account"] as? String
        let role: Int = args["role"] as! Int
        let request = ThingSmartHomeAddMemberRequestModel()
        request.name = name
        request.autoAccept = autoAccept
        if countryCode != nil {
            request.countryCode = countryCode!
        }

        request.role = ThingHomeRoleType(rawValue: role)!

        if account != nil {
            request.account = account!
        }

        ThingSmartHome(homeId: homeId).addMember(
            withAddMemeberRequestModel: request
        ) { data in
            if let data = data {
                print("addMember success: \(data)")
                result(data["memberId"])
            }
            result(nil)
        } failure: { error in
            if let error = error as? NSError {
                print("addMember failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }

    private func queryMemberList(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let homeId = args["homeId"] as! Int64
        ThingSmartHome(homeId: homeId).getMemberList { list in
            let data: [[AnyHashable: Any]] =
                (list?.map { (member) -> [AnyHashable: Any] in
                    var dict: [AnyHashable: Any] = [:]
                    dict["memberId"] = member.memberId
                    dict["name"] = member.name
                    dict["homeId"] = member.homeId
                    dict["role"] = member.role.rawValue
                    dict["mobile"] = member.mobile
                    dict["userName"] = member.userName
                    dict["uid"] = member.uid
                    dict["memberStatus"] = member.dealStatus.rawValue

                    return dict
                })!
            result(data)
        } failure: { error in
            if let error = error as? NSError {
                print("queryMemberList failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }


    private func getMemberShareList(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        guard let devId = args["devId"] as? String else {
            result(FlutterError(code: "400", message: " getMemberShareList 缺少参数 devId", details: nil))
            return
        }
        var deviceShare = ThingSmartHomeDeviceShare()
        deviceShare.getMemberList(withDevId: devId, success: { (list) in
             let data: [[AnyHashable: Any]] =
                (list.map { (member) -> [AnyHashable: Any] in
                    var dict: [AnyHashable: Any] = [:]
                    dict["memberId"] = member.memberId
                    dict["nickName"] = member.nickName
                    dict["userName"] = member.userName
                    dict["iconUrl"] = member.iconUrl

                    dict["uid"] = member.uid
                    return dict
                })
                result(data)
        }, failure: { (error) in
            if let error = error as? NSError {
                print("getMemberShareList failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        })
    }

    private func removeMember(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let memberId = args["memberId"] as! Int64
        ThingSmartHomeMember().removeHomeMember(withMemberId: memberId) {
            result(true)
        } failure: { error in
            if let error = error as? NSError {
                print("removeMember failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }

    private func getlatestMessage(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let message = ThingSmartMessage()
        message.getLatestMessage(success: {dic in
            guard let values = dic?.values else {
                result(false)
                return
            }
            let hasUnread = values.contains { value in
                if let number = value as? NSNumber {
                    return number.intValue != 0
                }
                if let intValue = value as? Int {
                    return intValue != 0
                }
                return false
            }
            result(hasUnread)
        }, failure: {error in
            if let error = error as? NSError {
                print("getLatestMessage failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        });

    }

   

    private func modifyMember(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()

        let name = args["name"] as? String
        let role = args["role"] as? Int
        let memberId = args["memberId"] as! Int64
        let request = ThingSmartHomeMemberRequestModel()
        request.memberId = memberId

        if let name = name {
            request.name = name
        }

        if let role = role {
            request.role = .init(rawValue: role)!
        }

        ThingSmartHomeMember().updateHomeMemberInfo(with: request) {
            result(true)
        } failure: { error in
            if let error = error as? NSError {
                print("modifyMember failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }

    private func joinHome(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let code = args["code"] as! String
        ThingSmartHomeInvitation().joinHome(withInvitationCode: code) { res in
            result(res)
        } failure: { error in
            if let error = error as? NSError {
                print("joinHome failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }

    private func cancelInvitation(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let invitationID = args["invitationID"] as! Int
        ThingSmartHomeInvitation().cancelInvitation(
            withInvitationID: NSNumber(value: invitationID)
        ) { res in
            result(res)
        } failure: { error in
            if let error = error as? NSError {
                print("cancelInvitation failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }



          
private func openRNDebugConfig(
    _ call: FlutterMethodCall,
    result: @escaping FlutterResult
) {
    let debugConfig = "openRNDebugConfig"
    
    if let service = ThingModule.routeService() {
        service.openRoute(debugConfig, withParams: nil)
    } else {
        print("⚠️ routeService is nil")
    }
}


    private func acceptOrRejectInvitation(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let homeId = args["homeId"] as! Int64
        let accept = args["accept"] as! Bool
        ThingSmartHome(homeId: homeId).joinFamily(withAccept: accept) { res in
            result(res)
        } failure: { error in
            if let error = error as? NSError {
                print("acceptOrRejectInvitation failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }

    private func queryInvitation(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let homeId = args["homeId"] as! Int64
        ThingSmartHomeInvitation().fetchRecordList(withHomeID: homeId) { list in
            let data: [[String: Any]] = list.map { (item) -> [String: Any] in
                var dict: [String: Any] = [:]
                dict["invitationID"] = item.invitationID
                dict["invitationCode"] = item.invitationCode
                dict["name"] = item.name
                dict["dealStatus"] = item.dealStatus.rawValue
                dict["validTime"] = item.validTime
                dict["role"] = item.role.rawValue

                return dict
            }
            result(data)
        } failure: { error in
            if let error = error as? NSError {
                print("acceptOrRejectInvitation failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }

    private func modifyInvitation(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let invitationId = args["invitationId"] as! Int64
        let name = args["name"] as! String
        let role = args["role"] as! Int
        let request = ThingSmartHomeInvitationInfoRequestModel()
        request.invitationID = NSNumber(value: invitationId)
        request.name = name
        request.role = .init(rawValue: role)!
        ThingSmartHomeInvitation().updateInvitationInfo(with: request) { res in
            result(res)
        } failure: { error in
            if let error = error as? NSError {
                print("modifyInvitation failure: \(error)")
                result(
                    FlutterError(
                        code: error.code.description,
                        message: error.description,
                        details: error.debugDescription
                    )
                )
            }
        }

    }
     
     
     private func gotoMessage(
         _ call: FlutterMethodCall,
         result: @escaping FlutterResult
     ) {
         
         DispatchQueue.main.async(execute: {
             let impl = ThingSmartBizCore.sharedInstance().service(of: ThingMessageCenterProtocol.self) as? ThingMessageCenterProtocol
             
             guard let impl = impl else {
                 result(
                     FlutterError(
                         code: "-1",
                         message: "Message service unavailable",
                         details: "Message service unavailable"
                     )
                 )

                 return;
             }
             
             impl.gotoMessageCenterViewControllerWith(animated: true)
             })
             
         }
     
 
    private func gotoPanel(
        _ call: FlutterMethodCall,
        result: @escaping FlutterResult
    ) {
        let args = call.arguments as? [String: Any] ?? [String: Any]()
        let deviceId = args["deviceId"] as! String
        
        let initialPropos = args["initialPropos"] as? [String: Any]
        let contextProps = args["contextProps"] as? [String: Any]
        
        let device = ThingSmartDevice(deviceId: deviceId)
        let model = device?.deviceModel
        guard let model = model else {
            // error

                print("gotoPanel failure: model = null")
                result(
                    FlutterError(
                        code: "-1",
                        message: "model == null",
                        details: "model == null"
                    )
                )
            return
        }
        
        guard let panelService = ThingSmartBizCore.sharedInstance().service(of: ThingPanelProtocol.self) as? ThingPanelProtocol else {
            print("gotoPannel failure: panel service unavailable")
            result(
                FlutterError(
                    code: "-1",
                    message: "Panel service unavailable",
                    details: "Panel service unavailable"
                )
            )
            return
        }
//
//        panelService.cleanPanelCache()
        
        // 填充context， router， config参数
//        let propos = ["context": [:], "router": [:], "config": [:]]
        DispatchQueue.main.async(execute: {
            panelService.getPanelViewController(with: model,
                                              initialProps: initialPropos,
                                              contextProps: contextProps,
                                              completionHandler: { (vc, error) in
                DispatchQueue.main.async {
                    self.getPanelDetailView(withDeviceModel: model, completion: nil)
                    let rootVc = UIApplication.shared
                        .connectedScenes
                        .compactMap { $0 as? UIWindowScene }
                        .flatMap { $0.windows }
                        .first { $0.isKeyWindow }?
                        .rootViewController
                    if let navc = rootVc as? UINavigationController, let vc = vc {
                        navc.pushViewController(vc, animated: true)
                    }
                    
                }
            })
            
        })
    }
    
    private func getPanelDetailView(withDeviceModel deviceModel: ThingSmartDeviceModel,
                                    completion: ((_ viewController: UIViewController?, _ error: Error?) -> Void)? )
            {
                guard let impl = ThingSmartBizCore.sharedInstance().service(of: ThingDeviceDetailProtocol.self) as? ThingDeviceDetailProtocol else {
                    completion?(nil, NSError(domain: "com.yourdomain.error", code: 500, userInfo: [NSLocalizedDescriptionKey: "Panel service unavailable"]))
                    return
                }


             //   impl.clearInsertItem() // 插入前清空数据
       
                if(deviceModel.isShare == false)
                {
                    impl.insertDevMenuItemAsync({ (type, deviceModel, groupModel, complete) in
                            //耗时操作
                            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                                let model = CustomMenuModel.init()
                                if groupModel != nil {
                                    model.title = "设备共享" //设备共享，售后服务，问题反馈
                                    model.detail = ""
                                }else{
                                    model.title = "设备共享"
                                    model.detail = ""
                                }
                                complete(model);
                            }
                        }
                     , customType: "c_share_device");
                }

                
                impl.insertDevMenuItemAsync({ (type, deviceModel, groupModel, complete) in
                        //耗时操作
                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                            let model = CustomMenuModel.init()
                            if groupModel != nil {
                                model.title = "意见反馈" //设备共享，售后服务，问题反馈
                                model.detail = ""
                            }else{
                                model.title = "意见反馈"
                                model.detail = ""
                            }
                            complete(model);
                        }
                    }
                 , customType: "c_help_and_feedback");
                impl.insertDevMenuItemAsync({ (type, deviceModel, groupModel, complete) in
                        //耗时操作
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                            let model = CustomMenuModel.init()
                            if groupModel != nil {
                                model.title = "预约报修" //设备共享，售后服务，意见反馈
                                model.detail = ""
                            }else{
                                model.title = "预约报修"
                                model.detail = ""
                            }
                            complete(model);
                        }
                    }
                 , customType: "c_device_repair_report");
                
                impl.clickMenuItem({ (type, deviceModel, groupModel) in
                    if type == "c_share_device" {
                        // 设备共享
                        print("点击了设备共享")

                         if let devId = deviceModel?.devId {
                             self.pushFlutterVC(path: "/device_share_list", devId: devId)
                         }
                    } else if type == "c_help_and_feedback" {
                        // 帮助与反馈
                        print("点击了帮助与反馈")
                        if let devId = deviceModel?.devId {
                            self.pushFlutterVC(path: "/feed_back_help", devId: devId)
                        }
                    } else if type == "c_device_repair_report" {
                        // 设备报修
                        print("点击了设备报修")
                        if let devId = deviceModel?.devId {
                            self.pushFlutterVC(path: "/device_report_repair", devId: devId)
                        }
                    }
                })
            }
     



     private func pushFlutterVC(path: String, devId: String? = nil) {
         let rootNavVC = UIApplication.shared
             .connectedScenes
             .compactMap { $0 as? UIWindowScene }
             .flatMap { $0.windows }
             .first { $0.isKeyWindow }?
             .rootViewController as? UINavigationController
         guard let rootNavVC = rootNavVC else { return }
         
    DispatchQueue.main.async {
        // 如果当前顶部已经是 FlutterViewController，则直接下发路由
        if rootNavVC.topViewController is FlutterViewController {
            var args: [String: Any] = ["path": path]
            if let devId = devId { args["devId"] = devId }
            self.channel?.invokeMethod("pushFlutterVC", arguments: args)
            return
        }

        // 单引擎多VC：用同一个engine创建新的FlutterViewController，保证Provider共享但返回正确
        guard let engine = self.engine else { return }
        
        
        var args: [String: Any] = ["path": path]
        if let devId = devId { args["devId"] = devId }
        self.channel?.invokeMethod("pushFlutterVC", arguments: args)
    
        engine.viewController = nil
        let vc = TuyaFlutterViewController(engine: engine, nibName: nil, bundle: nil)
        // 确保新VC的背景是不透明的
        vc.view.backgroundColor = .white
       
        
        // 延迟push，否则在动画过程中能看到底层flutter的页面内容
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
            rootNavVC.pushViewController(vc, animated: true)
        }
    }

    
}



     // 原生侧返回
     private func nativePop() {
         let rootNavVC = UIApplication.shared
             .connectedScenes
             .compactMap { $0 as? UIWindowScene }
             .flatMap { $0.windows }
             .first { $0.isKeyWindow }?
             .rootViewController as? UINavigationController
         guard let nav = rootNavVC else { return }
         
        // 在pop之前，先detach当前的FlutterViewController
        if let engine = self.engine,
            let currentFlutterVC = nav.topViewController as? FlutterViewController {
            if engine.viewController === currentFlutterVC {
                engine.viewController = nil
            }
        }
        
        nav.popViewController(animated: true)
        DispatchQueue.main.async {
            // 单引擎多VC：pop后从栈中寻找 FlutterViewController 再重新 attach
            if let engine = self.engine,
               let newTopFlutterVC = nav.viewControllers
                    .reversed() // 从顶部往下找
                    .first(where: { $0 is FlutterViewController }) as? FlutterViewController {
                engine.viewController = newTopFlutterVC
                // 确保底层VC的视图可见（之前可能被隐藏了）
                newTopFlutterVC.view.isHidden = false
                newTopFlutterVC.view.alpha = 1.0
            }
            
            // 切换Flutter端路由到/main
            self.channel?.invokeMethod("popFlutterVC", arguments: [])
            
             // 恢复可能被修改的导航栏与交互状态
             nav.setNavigationBarHidden(false, animated: false)
             nav.view.isUserInteractionEnabled = true
             nav.topViewController?.view.isUserInteractionEnabled = true
              nav.view.gestureRecognizers?.forEach { $0.isEnabled = true }
              nav.interactivePopGestureRecognizer?.isEnabled = true
              if UIApplication.shared.isIgnoringInteractionEvents {
                  UIApplication.shared.endIgnoringInteractionEvents()
              }
              nav.view.setNeedsLayout()
              nav.view.layoutIfNeeded()

         }
     }

    
     
}

// 单个设备状态的回调
@available(iOS 13.0, *)
extension TuyaHomeSdkFlutterPlugin: ThingSmartDeviceDelegate {
    open func device(
        _ device: ThingSmartDevice,
        dpsUpdate dps: [AnyHashable: Any]
    ) {
        print(" DPS Update \(dps)")
        let event: [String: Any] = [
            "type": "dpsUpdate",
            "deviceId": device.deviceModel.devId ?? "",
            "dps": dps ?? [:]
        ]
        self.deviceSink.deviceInfoSink?(event)
       

    }

    open func deviceRemoved(_ device: ThingSmartDevice) {
        print(" Device Removed")
        let event: [String: Any] = [
            "type": "removed",
            "deviceId": device.deviceModel.devId ?? "",
        ]
        self.deviceSink.deviceInfoSink?(event)
    
    }

    open func deviceInfoUpdate(_ device: ThingSmartDevice) {
        print(" Device Info Update")
        let event: [String: Any] = [
            "type": "infoUpdate",
            "deviceId": device.deviceModel.devId ?? "",
            "model": self._modelToDict(deviceModel: device.deviceModel)
        ]
        self.deviceSink.deviceInfoSink?(event)
    
    }
}

@available(iOS 13.0, *)


@available(iOS 13.0, *)
extension TuyaHomeSdkFlutterPlugin: ThingSmartHomeDelegate
{
    /// thingSmartHomeDelegate
    open  func homeDidUpdateInfo(_ home: ThingSmartHome!) {
        var event: [String: Any] = ["type": "homeInfoUpdate"]
        if let homeId = home?.homeModel?.homeId {
            event["homeId"] = homeId
        }
        homeInfoUpdateHandler.homeUpdateSink?(event)
      }


      // 我收到的共享设备列表变化(测试得到：收到共享时回调)
    open   func homeDidUpdateSharedInfo(_ home: ThingSmartHome!) {
        var event: [String: Any] = ["type": "sharedInfoUpdate"]

    
  
        if let homeId = home?.homeModel?.homeId {
            event["homeId"] = homeId
        }
        homeInfoUpdateHandler.homeUpdateSink?(event)
      }

      // 家庭下新增房间代理回调
    open   func home(_ home: ThingSmartHome!, didAddRoom room: ThingSmartRoomModel!) {
          //...
      }



      // 房间信息变更，例如 name
    open   func home(_ home: ThingSmartHome!, roomInfoUpdate room: ThingSmartRoomModel!) {
    //        reload()/
      }

      // 房间与设备，群组的关系变化
    open   func home(_ home: ThingSmartHome!, roomRelationUpdate room: ThingSmartRoomModel!) {

      }

      // 添加设备
    open  func home(_ home: ThingSmartHome!, didAddDeivice device: ThingSmartDeviceModel!) {
        var event: [String: Any] = [
            "type": "deviceAdded",
            "deviceId": device?.devId ?? "",
            "deviceModel": self._modelToDict(deviceModel: device)
        ]
        if let homeId = home?.homeModel?.homeId {
            event["homeId"] = homeId
        }
        homeInfoUpdateHandler.homeUpdateSink?(event)
      }

      // 删除设备
    open   func home(_ home: ThingSmartHome!, didRemoveDeivice devId: String!) {
        var event: [String: Any] = [
            "type": "deviceRemoved",
            "deviceId": devId ?? ""
        ]
        if let homeId = home?.homeModel?.homeId {
            event["homeId"] = homeId
        }
        homeInfoUpdateHandler.homeUpdateSink?(event)
      }

      // 设备信息更新，例如 name
    open   func home(_ home: ThingSmartHome!, deviceInfoUpdate device: ThingSmartDeviceModel!) {
        var event: [String: Any] = [
            "type": "deviceInfoUpdate",
            "deviceId": device?.devId ?? "",
            "model": self._modelToDict(deviceModel: device)
        ]
        if let homeId = home?.homeModel?.homeId {
            event["homeId"] = homeId
        }
        homeInfoUpdateHandler.homeUpdateSink?(event)
      }

      // 家庭下设备的 dps 变化代理回调
    open   func home(_ home: ThingSmartHome!, device: ThingSmartDeviceModel!, dpsUpdate dps: [AnyHashable : Any]!) {
        var event: [String: Any] = [
            "type": "deviceDpsUpdate",
            "deviceId": device?.devId ?? "",
            "dps": dps
        ]
        if let homeId = home?.homeModel?.homeId {
            event["homeId"] = homeId
        }
        homeInfoUpdateHandler.homeUpdateSink?(event)
      }

      // 添加群组
    open   func home(_ home: ThingSmartHome!, didAddGroup group: ThingSmartGroupModel!) {

      }

      // 删除群组
    open  func home(_ home: ThingSmartHome!, didRemoveGroup groupId: String!) {

      }

      // 群组信息更新，例如 name
    open   func home(_ home: ThingSmartHome!, groupInfoUpdate group: ThingSmartGroupModel!) {

      }

      // 家庭下群组的 dps 变化代理回调
    open  func home(_ home: ThingSmartHome!, group: ThingSmartGroupModel!, dpsUpdate dps: [AnyHashable : Any]!) {
                //...
      }

      // 家庭下设备的告警信息变化的代理回调
    open  func home(_ home: ThingSmartHome!, device: ThingSmartDeviceModel!, warningInfoUpdate warningInfo: [AnyHashable : Any]!) {
        var event: [String: Any] = [
            "type": "deviceWarningUpdate",
            "deviceId": device?.devId ?? "",
            "warningInfo": warningInfo ?? [:]
        ]
        if let homeId = home?.homeModel?.homeId {
            event["homeId"] = homeId
        }
        homeInfoUpdateHandler.homeUpdateSink?(event)
      }


}

@available(iOS 13.0, *)
extension TuyaHomeSdkFlutterPlugin: ThingSmartBLEWifiMultierDelegate {
    public func bleWifiMuliter(
        _ muliter: ThingSmartBLEWifiMultier,
        didStartActive advModel: ThingBLEAdvModel
    ) {
        if let uuid = advModel.uuid?.lowercased(), uuid.isEmpty == false {
            discoveredAdvModels[uuid] = advModel
        }
    }

    public func bleWifiMuliter(
        _ muliter: ThingSmartBLEWifiMultier,
        startFailDevice advModel: ThingBLEAdvModel,
        error: Error
    ) {
        let uuid = advModel.uuid?.lowercased() ?? ""
        if uuid.isEmpty == false {
            discoveredAdvModels.removeValue(forKey: uuid)
        }
        var event: [String: Any] = [
            "success": false,
            "uuid": uuid
        ]
        let nsError = error as NSError
        event["errorCode"] = nsError.code
        event["errorMessage"] = nsError.localizedDescription
        
        if let jsonData = try? JSONSerialization.data(withJSONObject: event, options: []),
           let jsonString = String(data: jsonData, encoding: .utf8) {
            print("119615 bleWifiMuliter startFailDevice\(jsonString)")
        } else {
            print("119615 bleWifiMuliter  startFailDevice \(event)")
        }
        
        batchConfigHandler.batchSink?(event)
    }

    public func bleWifiMuliter(
        _ muliter: ThingSmartBLEWifiMultier,
        didReceiveBLEWifiConfigDevice deviceModel: ThingSmartDeviceModel?,
        error: Error?
    ) {
        
        let uuid = deviceModel?.uuid?.lowercased()
        if let uuid = uuid {
            discoveredAdvModels.removeValue(forKey: uuid)
        }
        var event: [String: Any] = [
            "success": error == nil,
            "uuid": uuid ?? ""
        ]
        if let model = deviceModel {
            event["device"] = _modelToDict(deviceModel: model)
        }
        if let nsError = error as NSError? {
            event["errorCode"] = nsError.code
            event["errorMessage"] = nsError.localizedDescription
        }
        if let jsonData = try? JSONSerialization.data(withJSONObject: event, options: []),
           let jsonString = String(data: jsonData, encoding: .utf8) {
            print("119615 bleWifiMuliter  didReceiveBLEWifiConfigDevice\(jsonString)")
        } else {
            print("119615 bleWifiMuliter  didReceiveBLEWifiConfigDevice \(event)")
        }
        batchConfigHandler.batchSink?(event)
    }
}

extension TuyaHomeSdkFlutterPlugin: ThingSmartBLEManagerDelegate,
    ThingSmartBLEWifiActivatorDelegate, ThingSmartActivatorDelegate
{
    // When the device connected to the router and activate itself successfully to the cloud, this delegate method will be called.
    open func bleWifiActivator(
        _ activator: ThingSmartBLEWifiActivator,
        didReceiveBLEWifiConfigDevice deviceModel: ThingSmartDeviceModel?,
        error: Error?
    ) {
        let resolvedUUID = (deviceModel?.uuid ?? extractUUID(from: activator))?.lowercased()
        if let error = error as? NSError ,
           let uuid = resolvedUUID {
          
            finishBleWifiConfig(
                for: uuid,
                withError: FlutterError(
                    code: error.code.description,
                    message: error.description,
                    details: error.debugDescription
                )
            )
            return
        }
        guard let uuid = resolvedUUID else { return }
        guard let deviceModel = deviceModel else {
            finishBleWifiConfig(
                for: uuid,
                withError: FlutterError(
                    code: "-1",
                    message: "配网失败",
                    details: "配网失败"
                )
            )
            return
        }
        let dict = self._modelToDict(deviceModel: deviceModel)
        finishBleWifiConfig(for: uuid, withSuccess: dict)
    }
    
    public func activator(
        _ activator: ThingSmartActivator,
        didReceiveDevice deviceModel: ThingSmartDeviceModel?,
        error: (any Error)?
    ) {

        guard error == nil,
            let deviceModel = deviceModel
        else {
            self.callback?(
                FlutterError(
                    code: "Config",
                    message: "Cannot config WiFi",
                    details: nil
                )
            )
            return
        }
        let dict = self._modelToDict(deviceModel: deviceModel)
        self.callback?(dict)
    }

    /// Discover devices
    public func didDiscoveryDevice(withDeviceInfo deviceInfo: ThingBLEAdvModel)
    {
        print(" uuid \(String(describing: deviceInfo.uuid))")
        if let uuid = deviceInfo.uuid?.lowercased() {
            discoveredAdvModels[uuid.lowercased()] = deviceInfo
        }

        ThingSmartBLEManager.sharedInstance().queryDeviceInfo(
            withUUID: deviceInfo.uuid,
            productId: deviceInfo.productId,
            success: {
                (info) in

                guard let info else {
                    return
                }
                var device = [String: Any]()
                device["productId"] = deviceInfo.productId
                device["uuid"] = deviceInfo.uuid?.lowercased()
                device["name"] = info["name"]
                device["iconUrl"] = info["icon"]
                device["mac"] = deviceInfo.mac
                self.deviceDiscoveryHandler.discoverySink?(device)
//                self.callback?(device)
                //            self._stopConfiguring()
            },
            failure: {
                (error) in
                if let error = error as? NSError {
                    print("getToken failure: \(error)")
                    self.callback?(
                        FlutterError(
                            code: error.code.description,
                            message: error.description,
                            details: error.debugDescription
                        )
                    )
                }
            }
        )
    }
}



class CustomMenuModel: NSObject, ThingDeviceDetailCustomMenuModel{
    var title : String?
    var detail : String?
}

extension FlutterPluginRegistrar {
    func getEngine() throws -> FlutterEngine {
        let messenger = messenger()
        // Swift 5.7+ 的更安全方式
        let mirror = Mirror(reflecting: messenger)
        let paths = [
               "_engine",
               "binaryMessenger._engine",
               "engine"
           ]
           
           for path in paths {
               if let engine = mirror.descendant(path) as? FlutterEngine {
                   return engine
               }
           }
        
        throw EngineError.engineNotFound
    }
}

enum EngineError: Error {
    case messengerTypeMismatch
    case engineNotFound
}
